<?php
/*=============================================================================
|| ##################################################################
||	phpFoX Konsort
|| ##################################################################
||
||	Copyright		: (C) 2005-2007 PHPFOX Limited a Reality Fox Creation
||	Contact			: info@phpfox.com
||
||	- phpFoX and all of its source code and files are protected by Copyright Laws.
||
||	- The license for phpFoX permits you to install this software on a single domain (.com, .org, .net, etc.).
||
||	- You may also not remove this copyright screen which shows the copyright information and credits for phpFoX (RealityFOX Creations).
||
||	- phpFoX Konsort is NOT a FREE software - http://www.phpfox.com/license/
||
|| ##################################################################
=============================================================================*/

/* $File: ./include/modules/Account/classes/PhpFox_ServiceAccount.class.php, $Author:  $ */



/** Account-related services (create, date, delete, list etc.)
 *
 * @package module.account
 * @version $Id: PhpFox_ServiceAccount.class.php 489 2008-09-17 10:12:57Z phpfoxsv $
 *
 */
class PhpFox_Mod_Account_ServiceAccount extends BaseService
{
    /** List accounts
     * @param array  $aCond     condition array
     * @param int    $iPage     page number
     * @param int    $iPageSize page size (row per page)
     * @param string $sOrder    order string
     * @return array account info
     */
    function &listAccounts($aCond = array(), $iPage=0, $iPageSize=0, $sOrder = '')
    {
        $oAcc = &$this->_oModule->getItem('Account');
        /* @var $aAcc Mod_Account_ItemAccount */

        $aRes = $oAcc->getList($aCond, $iPage, $iPageSize, $sOrder);
        return $aRes;
    }

    function getStuffList()
    {
        $aCond = array();
        $aCond['type'] = '<= 1';
        list($aItems, $iCnt) = $this->listAccounts($aCond);
        return array($aItems, $iCnt);
    }

    function getPrivacySettings()
    {
    	$aSettings = array();
		$aPrivacySettings = App::getParam('Mod_Account.privacy');
		foreach($aPrivacySettings as $sSetting)
		{
			$aSettings[] = App::format('Mod_Account.privacy.' . $sSetting);
		}
		return $aSettings;
    }

    /** Delete user picture
     *
     *
     * @param  string $sUserName
     * @return bool true
     */
    function deleteUserPicture($sUserName)
    {
        $sImagePath = App::getParam('user.pic.path');
        $aSuffixes = array
        (
        	'',
        	'_20',
        	'_50',
        	'_60',
        	'_75',
        	'_100',
        	'_120',
        );
        foreach ($aSuffixes as $sSuff)
        {
            if (file_exists($sImagePath.$sUserName.$sSuff.'.jpg'))
            {
                @unlink($sImagePath.$sUserName.$sSuff.'.jpg');
            }
            @copy(App::getParam('path').'design/pic/'.'noimage'.$sSuff.'.jpg', $sImagePath.$sUserName.$sSuff.'.jpg');
        }
        return true;
    }

    /** Get used space
     *
     * @param PhpFox_Mod_Acocunt_ItemAccount $oAcc user account
     * @return int user space
     */
    function getUsedSpace($sUser, $bDoCookie = true, $sUserId = 0, $bForceSet = false)
    {
    	if ( $bDoCookie && isset($_SESSION['used_space']) )
    	{
    		return $_SESSION['used_space'];
    	}

        $iUsedSpace = 0;

        $oSrvGallery = App::getModuleService('Gallery', 'Gallery');
        $iUsedSpace += $oSrvGallery->getUsedSpace($sUserId);

        $oSrvGroup = App::getModuleService('Groups', 'Groups');
        $iUsedSpace += $oSrvGroup->getUsedSpace($sUser);

        $oMusicService = &App::getModuleService('Music', 'Music');
        $iUsedSpace += $oMusicService->calcObtainedSpace($sUser);

        $oVideoService = &App::getModuleService('Video', 'Video');
        $iUsedSpace += $oVideoService->getUsedSpace($sUser);

        if ( $bDoCookie || $bForceSet )
        {
			// App::unsetSession('used_space');
       		App::setSession('used_space', $iUsedSpace);
       	}

        return $iUsedSpace;
    }


    /** Get user allowed space (0 -- unlimited)
     *
     * @param object $oUser user account object
     * @return mixed allowed space (in bytes)
     */
    function getAllowedSpace($oUser = null)
    {
        $oSrvSec = &$this->_oModule->getService('Security');
   		/* @var $oSrvSec PhpFox_Mod_Account_ServiceSecurity */
        if ($oUser == null)
        {
            $oUser = $oSrvSec->getCurrentUser();
        }
        if (!$oUser)
        {
            return false;
        }
        $aMembership = $oSrvSec->getUserMembershipData($oUser);
        return $aMembership['max_upload'];
    }

    /** List accounts as hash
     *
     *
     * @return array accounts hash
     */
    function &listAccountAsHash()
    {
        $oAcc = &$this->_oModule->getItem('account');
        /* @var $aAcc Mod_Account_ItemAccount */

        $aAccs = $oAcc->getHash('email');
        return $aAccs;
    }

    /** Get memberships list
     */
    function getMemberships()
    {
        $aMemberships = App::getParam('Mod_Account.memberships');
        foreach ($aMemberships as $iKey => $sName)
        {
            $aMemberships[$iKey] = App::format($sName);
        }
        return $aMemberships;
    }

    function setMembership($iUserId, $iMembershipId, $iMonth, $bAcceptNow)
    {
        $oAcc = &$this->_oModule->getItem('Account');
        /* @var $oAcc PhpFox_Mod_Account_ItemAccount */
        $iMembershipId = intval($iMembershipId);
        $iUserId = intval($iUserId);
        $iMonth = intval($iMonth);

        if ($bAcceptNow)
        {
    	    $sPayType=$oAcc->oDb->getField('SELECT ms.pay_type FROM `'.App::getT('membership').'` AS ms WHERE ms.membership_id="'.$iMembershipId.'"');
            if ($sPayType == 'onetime')
            {
                $iMonth = 360;
                $sLastPayment = "'2038-01-01 00:00:00'";
            }
            elseif ($sPayType == 'monthly')
            {
                $iMonth = 1;
                $sLastPayment = "now() + interval 1 month";
            }
			$aUpdate = array();
            if (isset($sLastPayment))
            {
            	$aUpdate['last_payment'] = $sLastPayment;
            }
            $aUpdate['type'] = $iMembershipId;
            $oAcc->oDb->update($oAcc->sTable, $aUpdate, '`id` = "' . $iUserId . '"');
        }
        else
        {
            $sSql = 'SELECT last_payment '.
                   ' FROM `user` '.
                   ' WHERE id = '.$iUserId;
            $sLastPayment = $oAcc->oDb->getField($sSql);
            $aRow = array
            (
                'membership_id' => $iMembershipId,
                'user_id'       => $iUserId,
                'apply_date'    => $sLastPayment,
            );
            $oAcc->oDb->insert(App::getT('membership_pending'), $aRow);
        }
        return true;
    }

    function processPendingMemberships()
    {
    	return true;

        $oAcc = &$this->_oModule->getItem('Account');
        /* @var $oAcc PhpFox_Mod_Account_ItemAccount */

        $sSql = 'SELECT COUNT(*) '.
               ' FROM `'.App::getT('membership_pending').'` '.
               ' WHERE apply_date <= NOW()';
        if (!$oAcc->oDb->getField($sSql))
        {
            return false;
        }
        $sSql = 'SELECT user_id, membership_id, apply_date '.
               ' FROM `'.App::getT('membership_pending').'` '.
               ' WHERE apply_date <= NOW()';
        $aRows = $oAcc->oDb->getRows($sSql);
        foreach ($aRows as $aRow)
        {
            $this->setMembership($aRow['user_id'], $aRow['membership_id'], 1, true);
            $sSql = 'DELETE FROM `'.App::getT('membership_pending').'` WHERE user_id = '.$aRow['user_id'].' AND membership_id = '.$aRow['membership_id'].' AND apply_date = "'.$aRow['apply_date'].'"';
            $oAcc->oDb->query($sSql);
        }
        return true;
    }

    /** Delete user accounts
     */
    function delete($iId)
    {
    	phpFoXPlugins::call_phpfox_function('delete_user', $iId);
        $oAcc = $this->_oModule->getItem('Account');
		$this->_preDelete($iId);
    }

    /** Clear account-realtied information
     *
     */
    function _preDelete($iId)
    {
		$oCustomFieldService = &$this->_oModule->getService('CustomField');

        $aAcc = $this->oDatabase->getRow('SELECT id, user FROM '.App::getT('user').' WHERE id = "'. $iId .'"');

        if ( isset($aAcc['user']) )
        {
            $aDeleteFrom = array
            (
            	array('block' => array('user1', 'user')),
            	array('block' => array('user2', 'user')),
            	array('board' => array('user', 'user')),
            	array('board_view' => array('user', 'user')),
            	array('buddy_add' => array('user', 'user')),
            	array('buddy_add' => array('friend', 'user')),
            	array('chat' => array('userid', 'id')),
            	array('chat_online' => array('userid', 'id')),
            	//array('comments' => array('userid', 'id')),
            	array('contacts' => array('uid', 'id')),
            	array('custom_field2text' => array('user_id', 'id')),
            	array('custom_field2user' => array('user_id', 'id')),
            	//array('events' => array('user', 'user')),
            	//array('event_invite' => array('user', 'user')),
            	array('favorite' => array('user', 'user')),
            	array('favorite' => array('user1', 'user')),
            	//array('forum_reply' => array('user', 'user')),
            	//array('forum_topic' => array('user', 'user')),
            	//array('forum_view' => array('user', 'user')),
            	array('friends' => array('user', 'user')),
            	array('friends' => array('friend', 'user')),
            	array('invite' => array('user', 'user')),
            	//array('hot_quiz' => array('user', 'user')),
            	array('invite' => array('user', 'user')),
            	//array('journal' => array('user_id', 'id')),
            	array('listing_main' => array('user', 'user')),
            	array('mail' => array('to', 'user')),
            	array('mail' => array('from', 'user')),
            	array('mail_alert' => array('to_id', 'id')),
            	array('mail_alert' => array('user_id', 'id')),
            	array('msg_chat' => array('userid', 'id')),
            	array('msg_online' => array('userid', 'id')),
            	array('msg_request' => array('userid', 'id')),
            	array('msg_room' => array('userid', 'id')),
            	//array('online_session' => array('online_session_user', 'user')),
            	//array('page' => array('user', 'user')),
            	//array('polls' => array('user', 'user')),
            	//array('poll_vote' => array('user', 'user')),
            	//array('quiz_2' => array('user', 'user')),
            	//array('quiz_2' => array('user1', 'user')),
            	array('rating' => array('user', 'user')),
            	//array('session' => array('user', 'user')),
            	//array('site_session' => array('user', 'user')),
            	array('template' => array('user', 'user')),
            	array('user' => array('user', 'user')),
            	array('user_info' => array('user', 'user')),
            	array('user_rating' => array('rater', 'id')),
            	array('user_rating' => array('user', 'id')),
            	array('videos_comments' => array('cm_userid', 'id')),
            	array('videos_favorite' => array('user_id', 'id')),
            	array('videos_rating' => array('rate_userid', 'id'))
            );
            
        	$aParams = array('oAcc'=> $this->_oModule->getItem('Account'), 'aIds' => array($aAcc['id']) );
            $aCallBackList = array(
            	// module, service
            	array('Gallery','Gallery'),
            	array('Groups','Groups'),
            	array('Music','Music'),
            	array('Forum','Forum'),
            	array('Event', 'Event'),
            	array('Log', 'Log'),
            	array('Poll', 'Poll'),
            	array('Comments', 'Comment'),
            	array('Quiz','Quiz'),
            	array('Blog','Blog'),
            );
			
			foreach($aCallBackList as $aCallBAck)
			{
				$oSrv = &App::getModuleService($aCallBAck[0],$aCallBAck[1]);
				$oSrv->onDeleteAccount($aParams);
			}

			foreach($aDeleteFrom as $aValues)
			{
				foreach ($aValues as $sName => $aValue) 
				{
					$this->oDatabase->_delete(App::getT($sName), "`". $aValue[0] ."` = '". $aAcc[$aValue[1]] ."'");
				}
			}

        	$aPicSizes = App::getParam('user.pic.sizes');
            $sPicPath = App::getParam('user.pic.path');

            $aVideos = $this->oDatabase->getRows("SELECT vid_id, vid_type FROM ". App::getT('videos') ." WHERE vid_userid = '". $aAcc['id'] ."'");
            foreach($aVideos as $aVideo)
            {
            	$sVideoFile = App::getParam('video.path') . $aVideo['vid_id'] .".". $aVideo['vid_type'];
            	if ( file_exists($sVideoFile) )
            	{
            		unlink($sVideoFile);
            	}
            }

            $aVideos = $this->oDatabase->getRows("SELECT vid_id, vid_type FROM ". App::getT('videos_pending') ." WHERE vid_userid = '". $aAcc['id'] ."'");
            foreach($aVideos as $aVideo)
            {
            	$sVideoFile = App::getParam('video.path') . $aVideo['vid_id'] . "_pending". ".". $aVideo['vid_type'];
            	if ( file_exists($sVideoFile) )
            	{
            		unlink($sVideoFile);
            	}
            }
            
			$this->oDatabase->_delete(App::getT('videos'), "vid_userid = '". $aAcc['id'] ."'");
            $this->oDatabase->_delete(App::getT('videos_pending'), "vid_userid = '". $aAcc['id'] ."'");

			foreach($aPicSizes as $iSize)
            {
            	$sPicFile = $sPicPath.$aAcc['user'].'_'.$iSize.'.jpg';
                if (file_exists($sPicFile))
                {
                	unlink($sPicFile);
				}
			}

            $sPicFile = $sPicPath.$aAcc['user'].'.jpg';
            if (file_exists($sPicFile))
			{
				unlink($sPicFile);
			}

            $sPicFile = App::getParam('user_bg.pic.path').$aAcc['user'].'.jpg';
			if (file_exists($sPicFile))
			{
				unlink($sPicFile);
			}

			$oAdminService = &App::getModuleService('Admin', 'Admin');
        	$aItems = $oAdminService->getTableStatus();
        	foreach ($aItems as $aItem)
        	{
            	$oAdminService->optimizeTable($aItem['Name']);
        	}
		}
    }

    /** Get Account by condition (if there more than one account selected
     *                           then only first will be returned)
     * @param  string $sCond condition to load acconut.
     * @return Account
     */
	function &getByCondition($sCond)
	{
		$oAcc = &$this->_oModule->getItem('Account');
        /* @var $oAcc PhpFox_Mod_Account_ItemAccount */

		if (!$oAcc->loadByCondition($sCond))
		{
			$oAcc = null;
		}
		return $oAcc;
	}

	function &getUserDetails($sUser)
	{
		$oAcc = &$this->_oModule->getItem('Account');
        /* @var $oAcc PhpFox_Mod_Account_ItemAccount */

		$oAcc->aData = $this->oDatabase->getRow("SELECT * FROM ". App::getT('user') ." ".
			" WHERE ". (is_numeric($sUser) ? "id" : "user") ." = '". $this->oDatabase->escape($sUser) ."'");

		return $oAcc;
	}

    /** Get Account by username
     * @param  string $sCond condition to load acconut.
     * @return Account
     */
	function getById($iAccId)
	{
	    $oAcc = &$this->_oModule->getItem('Account');
        /* @var $oAcc PhpFox_Mod_Account_ItemAccount */
		if (!$oAcc->load($iAccId))
		{
    		$oAcc = null;
		}

		return $oAcc;
	}


    /** Get Account by username
     * @param  string $sCond condition to load acconut.
     * @return Account
     */
	function &getByUsername($sName)
	{
		$oAcc = &$this->getUserDetails($sName);
		return $oAcc;
	}

	/** Create new member.
	 *
	 * @param PhpFox_Mod_Account_ItemAccount $oAcc        new account object
	 * @param string                         $sVerifyPage verification link (for mail)
	 * @param int                            $iRefId      referral ID
	 * @return int new account id or false if error occured
	 */
	function create($oAcc, $sVerifyPage, $iRefId)
	{
		$oAcc->aData = $oAcc->_filterData($oAcc->aData, array(
		    'user',
		    'password',
		    'email',
		    'gender',
		    'location',
		    'city',
		    'state',
		    'zip',
		    'day',
		    'month',
		    'year',
		    'signup_ip',
		    'lang_file',
		));
		
	    //check username
	    if ($oAcc->oDb->getField('SELECT COUNT(*) FROM '.$oAcc->sTable.
	                             '  WHERE user = "'.$oAcc->aData['user'].'"'))
	    {
	        $this->addErrors(App::format('Mod_Account.error.user_exists', array($oAcc->aData['user'])) );
	    }

	    //check email
	    if ($oAcc->oDb->getField('SELECT COUNT(*) FROM '.$oAcc->sTable.
	                             '  WHERE email = "'.$oAcc->aData['email'].'"'))
	    {
	        $this->addErrors(App::format('Mod_Account.error.email_exists', array($oAcc->aData['email'])) );
	    }

	    if (! $this->getErrors())
	    {
		    $sVerifyCode = time();
	    	$oAcc->aData['verify'] = App::getSetting('signup_email') ? 1 : 0;
		    $oAcc->aData['verifycode'] = App::getSetting('signup_email') ? $sVerifyCode : '';
			$oAcc->aData['not_1'] = 2;
			$oAcc->aData['not_2'] = 2;
			$oAcc->aData['not_3'] = 2;
			$oAcc->aData['not_4'] = 2;
			$oAcc->aData['not_5'] = 2;
			if (!isset($oAcc->aData['type']))
			{
				$oAcc->aData['type']  = App::getParam('Mod_Account.membership.normal');
			}
			$oAcc->aData['signup'] = time();

		    $iAccId = $oAcc->insert();
		    if ($iAccId)
		    {
		        $this->_postCreate($oAcc, $sVerifyPage, $iRefId, $sVerifyCode);

        		$aCallbackParams = array(
        			'Account' => $oAcc,
        		);
		        BaseService::callback($this, 'create', $aCallbackParams);
		        App::plugin_createUser($oAcc);
		        return $iAccId;
		    }
		    else
		    {
		        $this->addErrors($oAcc->getErrors());
		    }
	    }

	    return false;
	}

	/** Account post-create processing. (send mail, create related records etc.)
	 *
	 * @param PhpFox_Mod_Account_ItemAccount $oAcc        user account
	 * @param string                         $sVerifyPage verification link (for mail)
	 * @param int                            $iRefId      referral ID
	 */
	function _postCreate(&$oAcc, $sVerifyPage, $iRefId, $sVerifyCode)
	{
        //add user info record
        $oUserInfo = $this->_oModule->getItem('UserInfo');
        if (!$oUserInfo->loadByCondition('user = "'.$oAcc->aData['user'].'"'))
        {
            $oUserInfo->aData['user'] = $oAcc->aData['user'];
            $oUserInfo->insert();
        }

	    //create template record
        $oTemplate = $this->_oModule->getItem('Template');
        $oTemplate->aData['user'] = $oAcc->aData['user'];
        $oTemplate->insert();

		$oSrvFriend = $this->_oModule->getService('Friends');

        //add specified admin to friends
        if ($sNewFriend = App::getSetting('new_friend'))
        {
            $oAddUser = $this->getByCondition('user = "'.$sNewFriend.'"');
            if ($oAddUser)
            {
                $oSrvFriend->addFriend($oAddUser, $oAcc);
            }
        }

        //add referral points for referral
        if ($iRefId)
        {
            $oParentAcc = $this->getById($iRefId);
            if ($oParentAcc)
            {
            	$oSrvFriend->UserAddBuddy($oParentAcc->aData['user'], $oAcc->aData['user']);
                $this->changeUserInfo($oParentAcc, 'invite', 1, false);
                $this->oDatabase->update(App::getT('invite'), array('type' => 1), "email = '" . $oAcc->aData['email'] . "'");
            }
        }

        //send email
        if (App::getSetting('signup_email'))
        {        	
        	$oMailer = &App::newObject('mail_Mailer');
    		$sVerifyLinkParams = array(
    			'id'   => $oAcc->aData[$oAcc->sId],
    		    'code' => md5($oAcc->aData['password']),
    		    'verify' => md5($sVerifyCode)
    		);
    		$aVars = array(
    			'SITENAME'    => App::getSetting('site_name'),
    			'USERNAME'    => $oAcc->aData['user'],
    		    'VERIFY_LINK' => App::makeUrl($sVerifyPage, $sVerifyLinkParams),
    		);

    		$oMailer->send('email_verify', $oAcc->aData['email'],
    		               App::format('Mod_Account.verify_email'), $aVars);
        }

        $oSrvInvite = &$this->_oModule->getService('Invite');
        $oSrvInvite->isInvitedByUser($oAcc->aData['email']);
	}

	/** Verify new user
	 *
	 * @param int    $iId
	 * @param string $sCode
	 * @param string $sVerify
	 * @return bool true - verify ok, false - otherwise
	 */
    function verifyNewUser($iId, $sCode, $sVerify)
    {
        if (!$iId || !$sCode) //missed parameter(s)
        {
            return false;
        }

        $oAcc = &$this->_oModule->getItem('Account');
        /* @var $oAcc PhpFox_Mod_Account_ItemAccount */
        if ($oAcc->load($iId)) //account not found
        {
        	if ((md5($oAcc->aData['password']) == $sCode) && $oAcc->aData['verify'] && (md5($oAcc->aData['verifycode']) == $sVerify))
	        {
	            $oAcc->aData['verify'] = 0;
	            $oAcc->aData['verifycode'] = '';
	            return $oAcc->update(array('verify', 'verifycode'));
	        }
        }


        return false;
    }

    /** Get top users
     *
     * @param array $aCond select condition
     * @param int   $iNumUser number of top users to select
     * @return array users array
     */
    function getTopUsers($aGenderId, $iNumUsers, $aFields = array())
    {
        $aTopUsers = $this->oDatabase->getRows("
        	SELECT 
        		u.user, u.user_rating, COUNT(r.user) AS total_votes
        	FROM `" . App::getT('user') . "` AS u
        		LEFT JOIN " . App::getT('user_rating') . " AS r ON(u.id = r.user)        		
        	WHERE gender = '" . $aGenderId . "' AND user_rating > 0       	
        	GROUP BY u.user
        	HAVING total_votes > 3
        	ORDER BY u.user_rating DESC LIMIT 0," . $iNumUsers . "        	
        ");
        return $aTopUsers;
    }


	/** Returns recent logged in user
	 *
	 * @param int $iNumLogins
	 * @param string $sType
	 * @return array
	 */
	function &getRecentLogins($iNumLogins, $sType = '')
	{
	    $oAcc = &$this->_oModule->getItem('Account');
		/* @var $oAcc PhpFox_Mod_Account_ItemAccount */

	    if($sType == 'group')
	    {
	        $sSql = 'SELECT user FROM '.App::getT('page').' WHERE `page` = "groups" ORDER BY `time` DESC LIMIT '.intval($iNumLogins);
	    }
	    else
	    {
	        $sSql = 'SELECT user FROM '.$oAcc->sTable.' ORDER BY login DESC LIMIT '.intval($iNumLogins);
	    }
	    $aUsers = $oAcc->oDb->getRows($sSql);
	    return $aUsers;
	}

	/** Get random featured member
	 *
	 * @return array|bool member info or false if no featured members yet
	 */
	function getRandFeaturedMember()
	{
	    $oAcc = &$this->_oModule->getItem('Account');
	    /* @var $oAcc PhpFox_Mod_Account_ItemAccount */
	    $iNumFeatMembers = $oAcc->oDb->getField('SELECT COUNT(*) FROM '.$oAcc->sTable.
	                                            '  WHERE feature=1');
	    if ($iNumFeatMembers)
	    {
	        //get random featured member id
	        $iPos = rand(0, $iNumFeatMembers-1);
            $iId = $oAcc->oDb->getField('SELECT id FROM '.$oAcc->sTable.
                                        '  WHERE feature = 1'.
                                        '  LIMIT '.$iPos.',1');
            $oAcc->load($iId);
            $oAcc->aData['age'] = $this->getAge($oAcc->aData);
            $oAcc->aData['gender'] = App::format('core.'. strtolower($oAcc->aData['gender']) .'');

            return $oAcc->aData;
	    }


	    return false;
	}

	/** Returns membership image (full url)
	 *
	 * @param PhpFox_Mod_Account_ItemAccount $oAcc member account object
	 * @return string full image path
	 */
	function getMembershipImage(&$oAcc)
	{
	    return $this->getMembershipImageByType($oAcc->aData['type']);
	}

	/** Returns membership image (full url)
	 *
	 * @param PhpFox_Mod_Account_ItemSecurity $oSec member secure object
	 * @param PhpFox_Mod_Account_ItemAccount $oAcc member account object
	 * @return string full image path
	 */
	function getMembershipImageSecure(&$oSec, &$oAcc)
	{
		$aRow = $oSec->getMembershipData($oAcc->aData['type']);
		$sImage = App::getParam('membership.pic.url').$aRow['img'];
	    return $sImage;
	}


	/** Returns membership image  (full url) by type id
	 *
	 * @param int $iType membership type (field `type` in user table)
	 * @return string full image path
	 */
	function getMembershipImageByType($iType)
	{
	    static $aImages = null; //membership images cache

	    if ($iType != '0' && empty($iType))
	    {
	    	return '';
	    }
	    
        if (!isset($aImages[$iType]))
        {
        	if ( file_exists(App::getParam('path') . 'file/cache/membership'. $iType .'.php') )
        	{
        		require App::getParam('path') . 'file/cache/membership'. $iType .'.php';
        		$aImages[$iType] = App::getParam('membership.pic.url').$this->details['img'];
        	}
        	else
        	{
            	$oDb = &Database::get();
            	$aRows = $oDb->getRows('SELECT membership_id, img FROM '.App::getT('membership'));
            	foreach($aRows as $aRow)
            	{
            	    $aImages[$aRow['membership_id']] = App::getParam('membership.pic.url').$aRow['img'];
            	}
            }
        }

		if ( !isset($aImages[$iType]) )
		{
			return '';
		}

        return $aImages[$iType];
	}

	/** Get user points (total)
	 * @param PhpFox_Mod_Account_ItemAccount $oAcc member account object
	 * @return int user's point (total)
	 */
    function getPoints(&$oAcc)
    {
    	if ( isset($_SESSION['local_points']) )
    	{
    		return $_SESSION['local_points'];
    	}

		$iPoints = intval($oAcc->oDb->getField('SELECT total FROM '.App::getT('user_info').
                                               '  WHERE user = "'.$oAcc->aData['user'].'"'));

		$_SESSION['local_points'] = $iPoints;

		return $iPoints;
    }

	/** Get user points (total)
	 * @param PhpFox_Mod_Account_ItemAccount $oAcc member account object
	 * @return int user's point (total)
	 */
    function getUserPoints(&$oAcc)
    {
		$iPoints = intval($oAcc->oDb->getField('SELECT total FROM '.App::getT('user_info').
                                               '  WHERE user = "'.$oAcc->aData['user'].'"'));
		return $iPoints;
    }

    /** Get point stars configuration (as array)
     * @param int $iPoint number of points
     * @return array start configuration
     */
    function getPointsStars(&$oAcc)
    {
        return $this->getStarsAsArray($this->getPoints($oAcc));
    }

    /** Points as star array
     *
     * @param int $iPoints user rating (points)
     * @return array stars configuration info
     */
    function getStarsAsArray($iPoints)
    {
        $aStars = App::getParam('Mod_Account.points');
        $iRate = 0;
        foreach($aStars as $iVal => $aStar)
        {
            if ($iPoints >= $iVal)
            {
                $iRate = $iVal;
                break;
            }
        }

        $aRes = array();
        foreach($aStars[$iRate] as $sStr=>$iNum)
        {
            for($i=1; $i<=$iNum; $i++)
                $aRes[] = $sStr;
        }
        return $aRes;
    }

	/** Calculate user's age
	 *
	 * @param array $aData users data (required: year, month, day)
	 * @return int user's age.
	 */
	function getAge($aData)
	{
	    $iAge = date('Y') - $aData['year'];
	    $iCurrDate = date('m') * 100 + date('d');
	    $iBirthDate = $aData['month'] * 100 + $aData['day'];
	    if ($iCurrDate < $iBirthDate)
	    {
	        $iAge--;
	    }
	    return $iAge;
	}

	/** Change user info (for rating)
	 *
	 * @param PhpFox_Mod_Account_ItemAccount $oUser  user's object
	 * @param string                         $sField field
	 * @param int                            $iDelta
	 * @return bool true - update ok, false - no update made (no user)
	 */
	function changeUserInfo($oUser, $sField, $iDelta = 1, $bSession = true)
	{
		if (!$oUser)
	    {
	    	return false;
	    }

	    if (!in_array($sField, array('gallery', 'journal', 'poll', 'quiz',
                                     'comment', 'forum', 'viewing', 'invite', 'music', 'video', 'video_comment')))
	    {
	        exit('Wrong field '.$sField);
	    }

//	    if ($bSession)
//	    {
	    	unset($_SESSION['local_points']);
//	    }

	    if (App::getParam('count_user_points'))
	    {
	    	switch($sField)
		    {
		    	case 'gallery':
		    		$iTotal = $oUser->oDb->getField("SELECT COUNT(*) FROM ". App::getT('main') ." WHERE user_id = '". $oUser->aData['id'] ."'");
		    		break;
		    	case 'journal':
		    		$iTotal = $oUser->oDb->getField("SELECT COUNT(*) FROM ". App::getT('journal') ." WHERE user_id = '". $oUser->aData['id'] ."'");
		    		break;
		    	case 'poll':
		    		$iTotal = $oUser->oDb->getField("SELECT COUNT(*) FROM ". App::getT('polls') ." WHERE user = '". $oUser->aData['user'] ."'");
		    		break;
		    	case 'quiz':
		    		$iTotal = $oUser->oDb->getField("SELECT COUNT(*) FROM ". App::getT('hot_quiz') ." WHERE user = '". $oUser->aData['user'] ."'");
		    		break;
		    	case 'comment':
		    	case 'video_comment':
		    		$iTotalComments = $oUser->oDb->getField("SELECT COUNT(*) FROM ". App::getT('comments') ." WHERE userid = '". $oUser->aData['id'] ."'");
		    		$iTotalVideos = $oUser->oDb->getField("SELECT COUNT(*) FROM ". App::getT('videos_comments') ." WHERE cm_userid = '". $oUser->aData['id'] ."'");
		    		$sField = 'comment';	    		
		    		$iTotal = ($iTotalVideos + $iTotalComments);
		    		break;
		    	case 'forum':
		    		$iTotal = $oUser->oDb->getField("SELECT COUNT(*) FROM ". App::getT('forum_topic') ." WHERE user = '". $oUser->aData['user'] ."'");
		    		$iTotal += $oUser->oDb->getField("SELECT COUNT(*) FROM ". App::getT('forum_reply') ." WHERE user = '". $oUser->aData['user'] ."'");
		    		break;
		    	case 'music':
		    		$iTotal = $oUser->oDb->getField("SELECT COUNT(*) FROM ". App::getT('music_song') ." WHERE user_id = '". $oUser->aData['id'] ."'");
		    		$iTotal += $oUser->oDb->getField("SELECT COUNT(*) FROM ". App::getT('music_album') ." WHERE user_id = '". $oUser->aData['id'] ."'");
		    		break;
		    	case 'video':
		    		$iTotal = $oUser->oDb->getField("SELECT COUNT(*) FROM ". App::getT('videos') ." WHERE vid_userid = '". $oUser->aData['id'] ."'");
		    		break;
		    }
	    }
	    
	   	if (!App::getParam('count_user_points') && ($sField == 'video_comment'))
	   	{
	   		$sField = 'comment';	
	   	}	   
	    
	   	if($iDelta==0)
	   		$iDelta = -1;
	    $sDelta = ($iDelta>0) ? ('+'.strval($iDelta)) : strval($iDelta);

	    //update field
	    if ( isset($iTotal) )
	    {
	    	$oUser->oDb->query('UPDATE '.App::getT('user_info').
	                       '  SET '.$sField.' = '.$iTotal.
	                       '  WHERE user = "'.$oUser->aData['user'].'"');
	    }
	    else
	    {
	    		$oUser->oDb->query('UPDATE '.App::getT('user_info').
	                       '  SET '.$sField.' = IF ( '.$sField.$sDelta.' >0, '.$sField.$sDelta.', 0 )'.
	                       '  WHERE user = "'.$oUser->aData['user'].'"');
		}

	    //update total
	    if (App::getParam('count_user_points'))
	    {	    
	    	$oUser->oDb->query('UPDATE '.App::getT('user_info').
	                       '  SET total = gallery + journal + poll + quiz + comment + forum + viewing + invite + music + video + bonus '.
	                       '  WHERE user = "'.$oUser->aData['user'].'"');
	    }
	    else
	    {
	    	$oUser->oDb->query('UPDATE '.App::getT('user_info').
	                       '  SET total = IF ( total'.$sDelta.' >0, total'.$sDelta.', 0 )'.
	                       '  WHERE user = "'.$oUser->aData['user'].'"');
	    }

//		$iPoints = intval($oUser->oDb->getField('SELECT total FROM '.App::getT('user_info').
//                                               '  WHERE user = "'.$oUser->aData['user'].'"'));

	    App::plugin_updateAccount($oUser);

//	    if ($bSession)
//		{
//			App::updateUserSpace();
//	    	$_SESSION['local_points'] = $iPoints;
//	    }
	    return true;
	}

	/** Check email uniqueness
	 *
	 * @param string $sEmail email to check
	 * @param string $sUser  username to skip during checking ("current user")
	 * @return bool true - email unique, false - otherwise
	 */
    function checkEmailUnique($sEmail, $sUser = '')
    {
        $oAcc = $this->_oModule->getItem('Account');
        $bEmailExist = $oAcc->loadByCondition('email ="'.$oAcc->oDb->escape($sEmail).'"  AND '.
                                              'user <> "'.$oAcc->oDb->escape($sUser).'"');
        if ($bEmailExist)
            $this->addErrors(App::format('Mod_Account.error.email_exists', array($oAcc->aData['email'])) );
        return !$bEmailExist;
    }

    function browseUsers($aTextCond = array(), $aJoinCond = array(), $aCond = array(), $iPage = 0, $iPageSize = 0, $sSort = '', $bOnline = false)
    {
        $oAccountItem = &$this->_oModule->getItem('Account');
        /* @var $oAccountItem PhpFox_Mod_Account_ItemAccount */
        $aMap = $oAccountItem->aFields;
        $iJoin = 0;
        $sJoinCond = '';
        $sCond = $oAccountItem->_parseCond($aCond, $aMap);        
        $sJoinCond2='';
        if ($aJoinCond)
        {
        	foreach ($aJoinCond as $iKey => $sJoin)
        	{
        	    $iKey++;
        		$sJoinCond2.=$sJoin.' OR ';
        	}
        	$iJoin++;
        	$sJoinCond2=substr($sJoinCond2,0,-3);
        }

        if ($aTextCond)
        {
        	foreach ($aTextCond as $iKey => $sJoin)
        	{
        	    $iKey++;
        		$sJoinCond .= ' JOIN ' . App::getT('custom_field2text') . ' AS cfText' . $iKey . ' ON(u.id = cfText' . $iKey . '.user_id AND ' . str_replace('cfText', 'cfText' . $iKey, $sJoin) . ')';
        	}
        	$iJoin++;
        }	

        if ($iJoin)
        {			
			$sSql = 'SELECT DISTINCT u.id '.
					($iJoin ? ', count(cf2u.user_id) as count ':'').
                    ' FROM `'.$oAccountItem->sTable.'` AS '.$oAccountItem->sAlias. '
                     LEFT JOIN ' . App::getT('custom_field2user') . ' AS cf2u ON(u.id=cf2u.user_id)'. 
                    ($bOnline ? (' LEFT JOIN `'.App::getT('online_session').'` AS o_s ON ( '.$oAccountItem->sAlias.'.user = o_s.online_session_user ) ' ) : '' ) .
                    ($sJoinCond ? $sJoinCond : '').
                    ' WHERE '.$sCond.($sJoinCond2 ? ' AND '.$sJoinCond2 : '').
                    ($bOnline ? (' AND o_s.online_session_id IS NOT NULL ') : '' ).
                    ' GROUP BY cf2u.user_id'.($sJoinCond2 ? ' having count='.count($aJoinCond).'' : '');
            $iCnt = $oAccountItem->oDb->countRows($sSql);
        }
        else
        {
            $sSql = 'SELECT DISTINCT COUNT(*) '.
                    ' FROM `'.$oAccountItem->sTable.'` AS '.$oAccountItem->sAlias.
                    ($bOnline ? (' LEFT JOIN `'.App::getT('online_session').'` AS o_s ON ( '.$oAccountItem->sAlias.'.user = o_s.online_session_user ) ' ) : '' ) .
                    ' WHERE '.$sCond.' '.
                    ($bOnline ? (' AND o_s.online_session_id IS NOT NULL ') : '' );
            $iCnt = $oAccountItem->oDb->getField($sSql);
        }

        $aRows = array();
        if ($iCnt)
        {
            $iOffset = $oAccountItem->_getOffset($iPage, $iPageSize, $iCnt);
            $sSql = 'SELECT DISTINCT u.id, u.user, u.year, u.month, u.day, u.location, u.gender, u.feature'.
                    ($iJoin ? ', count(cf2u.user_id) as count ':'').
                    ' FROM `'.$oAccountItem->sTable.'` AS '.$oAccountItem->sAlias.
                    ' LEFT JOIN ' . App::getT('custom_field2user') . ' AS cf2u ON(u.id=cf2u.user_id)'.
                    ($bOnline ? (' LEFT JOIN `'.App::getT('online_session').'` AS o_s ON ( '.$oAccountItem->sAlias.'.user = o_s.online_session_user ) ' ) : '' ) .
                  	($sJoinCond ? $sJoinCond : '').
                    ' WHERE '.$sCond.($sJoinCond2 ? ' AND '.$sJoinCond2 : '').
                    ($bOnline ? (' AND o_s.online_session_id IS NOT NULL ') : '' ).
                    ($iJoin ? ' GROUP BY cf2u.user_id HAVING count='.count($aJoinCond).'':'').
                    ($sSort?(' ORDER BY '.$sSort):'').
                    ($iPageSize?(' LIMIT '.$iOffset.','.$iPageSize):'');

            $aRows = $oAccountItem->oDb->getRows($sSql);
        }
        return array($aRows, $iCnt);
    }

    /** Check access to profile (isblocked, for friends only)
     *
     * @param PhpFox_Mod_Account_ItemAccount $oAcc      target user (whose profile try access)
     * @param PhpFox_Mod_Account_ItemAccount $oCurrUser current user (who try to access profile)
     * @return bool true - access permitted, false - access denied
     */
    function checkAccesToProfile($oAcc, $oCurrUser)
    {
        //check is blocked
        $oSrvBlock = &$this->_oModule->getService('Block');
        /* @var $oSrvBlock PhpFox_Mod_Account_ServiceBlock */
        if ($oSrvBlock->isBlocked($oAcc, $oCurrUser))
        {
            $this->addErrors(App::format('Mod_Account.error.user_block_you'));
            return false;
        }

        //check for friends only
        if ($oAcc->aData['friends_only'])
        {
            $oSrvFriends = &$this->_oModule->getService('Friends');
            /* @var $oSrvFriends PhpFox_Mod_Account_ServiceFriends */
            if (!$oSrvFriends->isFriend($oAcc, $oCurrUser))
            {
                $this->addErrors(App::format('Mod_Account.error.for_friends_only'));
                return false;
            }
        }

        return true; //all checks are passes - return true
    }

    /** Get pending account exceeded pending timeout
     *
     * @return array account info
     */
    function getPendingTooMuchAccounts()
    {
        $iTimeout = time() - 3600 * 24 * App::getParam('user.pending.lifetime');
        $oAcc = $this->_oModule->getItem('Account');
        list($aAccs) =  $oAcc->getList(array('verify="1" AND signup < '.$iTimeout));
        return $aAccs;
    }

    /** Delete pending account exceeded pending timeout
     */
    function purgePendingTooMuchAccounts()
    {
        $iTimeout = time() - 3600 * 24 * App::getParam('user.pending.lifetime');
        $oAcc = $this->_oModule->getItem('Account');
        $oAcc->oDb->query('DELETE FROM '.$oAcc->sTable.' WHERE verify="1" AND signup < '.$iTimeout);
    }

    /** Add profile view
     *
     */
    function addProfileView($sUser)
    {
        if (CAN_SET_COOKIE && !$this->_oModule->getSessVar('viewed_'.$sUser))
        {
            $this->oDatabase->query("UPDATE ". App::getT('user') ." SET views = views+1 WHERE user = '".$this->oDatabase->escape($sUser)."'");
            $this->_oModule->setSessVar('viewed_'.$sUser, 1);
        }
    }

    /**
     * Checks if user is online
     *
     * @param string $sUser Username
     * @return boolean 1 = online, 0 = offline
     *
     *
     */
    function isOnline($sUser)
    {
        $oAcc = $this->_oModule->getItem('Account');

        $sSql = ' SELECT COUNT(*) AS cnt FROM ' . App::getT('online_session') . ' WHERE online_session_user = "' . $oAcc->oDb->escape($sUser) . '" ';
        $aCnt = $oAcc->oDb->getRow($sSql);
        if ($aCnt['cnt'] > 0)
        {
            return 1;
        }
        return 0;
    }
}
?>